/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package music;

import java.util.Vector;
import javax.sound.midi.MidiEvent;
import music.types.NoteTypes;
import music.types.Volume;
import java.awt.*;
import java.util.Collection;
import music.global.CharacterMap;
import music.types.ClefType;
import music.types.Interval;
import music.types.MidiNote;
/**
 *
 * @author TJ
 */
public class Note extends AbstractNote {
    private boolean staccato=false, accent=false, fermata=false;
    private boolean dotted=false;
    private Volume volume;
    private Vector<MidiNote> notes;
    private ClefType clef=null;
    public Note(NoteTypes n){
        super(n);
        notes=new Vector<MidiNote>();
    }
    public Note(NoteTypes n,Collection<MidiNote> n2) {
        super(n);
        notes=new Vector<MidiNote>();
        addNotes(n2);
    }
    public Note(NoteTypes n, MidiNote n2){
        super(n);
        notes=new Vector<MidiNote>();
        notes.add(n2);
    }
    public ClefType getClef() {
        
        return clef;}
    public void play(Tempo t) {
        
    }
    public void addNotes(Collection<MidiNote> c) {
        for(MidiNote n : c) {
            notes.add(n);
        }
    }
    public void addNote(MidiNote n) {notes.add(n);}
    public void setNotes(Vector<MidiNote> x) {notes=x;}
    public Vector<MidiNote> getNotes() {return notes;}
    public MidiEvent getNoteMidiEvent(){return null;}
    public MidiNote getHighestNote() {
        MidiNote highest=null;
        for(MidiNote n :notes) {
            if(highest==null || n.getMidi()>highest.getMidi()) {
                highest=n;
            }
        }
        
        return highest;
    }
    public MidiNote getLowestNote() {
        MidiNote lowest=null;
        for(MidiNote n :notes) {
            if(lowest==null || n.getMidi()<lowest.getMidi()) {
                lowest=n;
            }
        }
        
        return lowest;
    }
    private int renderLedgerLines(Graphics g, int x, SpacingOptions s,MidiNote n, ClefType c) {
        int led=c.getLedgerLines(n);
        int cWid=CharacterMap.getWidth(NoteTypes.QUARTER.getCharacter(), s.getRenderFont("OpusRegular"));
        for(int i=led; i!=0;) {
            int y=getMeasure().getStaff().getBottomLine()-i*s.getLineSpacing();
            if(i>0) {
                y-=s.getLineSpacing()*4;
            }
            
            g.drawLine(x, y, x+5*cWid/4, y);
            if(i>0){i--;}else{i++;}
            
        }
        return cWid/4;
    }
    public void renderNote(Graphics g,SpacingOptions s,int x,ClefType c){
        MidiNote lowest=null;
        MidiNote highest=null;
        for(MidiNote n :notes) {
            if(lowest==null || n.getMidi()<lowest.getMidi()) {
                lowest=n;
            }
            if(highest==null || n.getMidi()>highest.getMidi()) {
                highest=n;
            }
        }
       
        if(clef!=null) { 
            c=clef;
        }
        x+=renderAccidentals(g, c,s,this.getMeasure().getStaff().getKeyAt(this.getMeasure()),x);
        int wid=0;
        if(highest!=null) {wid=renderLedgerLines(g,x,s,highest,c);}
        if(lowest!=null) {wid=renderLedgerLines(g,x,s,lowest,c);}
        x+=wid;
        boolean r=c.renderUpsideDown(this);
        
        for(MidiNote n : getNotes()) {
            
            getType().render(g, x, c.getRenderY(s, getMeasure().getStaff().getBottomLine(), n),s, r);
        }
        
    }
    public int renderAccidentals(Graphics g,ClefType c, SpacingOptions s, KeySignature k,int x) {
        int w=0;
        Font f=g.getFont();
        g.setFont(s.getRenderFont("OpusRegular"));
        for(MidiNote m :getNotes()) {
            int tmp=3*m.getAccidentalWidth(s)/4;
            if(tmp>w) {w=tmp;}
            int y=c.getRenderY(s, this.getMeasure().getStaff().getBottomLine(), m)-s.getLineSpacing()/2;
            g.drawString(m.getAccidental(), x, y);
        }
        g.setFont(f);
        return w+5;
    }
    private int accidentalWidth(SpacingOptions s, KeySignature k) {
        int w=0;
        for(MidiNote m :getNotes()) {
            int tmp=m.getAccidentalWidth(s);
            if(tmp>w) {w=tmp;}
           
            }
        return w+5;
    }
    public int calculateWidth(SpacingOptions s){
        return CharacterMap.getWidth(getType().getCharacter(), s.getRenderFont())
                +accidentalWidth(s,this.getMeasure().getStaff().getKeyAt(this.getMeasure()));
    }
    public static Note transpose(Note n,Interval i) {return null;}
    public Note transpose(Interval i) {return null;}

}
